package com.easily.factory.aop;

import java.lang.reflect.Method;

public abstract class ProxyObject {
    // 代理的目标
    protected final Object targetObject;
    // aop切面信息执行器
    protected final AopObject aop;

    private final boolean isAllMethodProxy;

    // 进入该构造方法前，应判断targetObject是否匹配该代理aop
    protected ProxyObject(Object targetObject, AopObject aop,boolean isAllMethodProxy) {
        if (targetObject == null || aop == null) {
            throw new NullPointerException("target or aopObject should not be null");
        }
        this.targetObject = targetObject;
        this.aop = aop;
        this.isAllMethodProxy = isAllMethodProxy;
    }

    protected Object proxyInvoke(Method method, Object[] args,MethodInvokeFunc func) throws Throwable {
        // 判断该方法是否需要代理
        Object result = null;
        if (isAllMethodProxy || aop.isAopMethod(method.getName())){
            MethodBody methodBody = new MethodBody(targetObject, method, args);
            aop.advice(methodBody);
            try {
                result = func.invoke();
                aop.afterAdvice(methodBody);
            } catch (Throwable e) {
                aop.exceptionAdvice(methodBody, e);
            } finally {
                aop.finallyAdvice(methodBody);
            }
        }else{
            result = func.invoke();
        }
        return result;
    }

    public abstract  <T> T getProxy(Class<T> z);
}
